【MediaPipe】Jetson Nanoで環境構築し、CPU/GPUで動かしてみた(v0.7.5)
カフェチームの山本です。
今までMediaPipeを動かしてきましたが、使用していた環境はデスクトップPC・クラウドでした。
前回は、エッジ側で安価なデバイスで処理するために、MediaPipeをシングルボードで動かすことを目的として、MediaPipeをRaspberry Pi 4にインストールする方法を調べました。しかし、結果として処理速度が1[fps]であり、少しパワー不足感がありました。
今回は、RasPi4に代えて、MediaPipeをJetson Nanoにインストールして実行する方法を調べました。Hello Worldで動作確認し、Multi Hand Tracking CPU/GPU版をビルドし、動作することを確認しました。
基本的にMediaPipeの公式ガイド通りに進めて実行できました。途中、ビルド済みのbazelのバイナリファイルを利用しました。結果として、CPUを用いた場合は1[fps]程度、GPUを用いた場合は3~4[fps]程度で、Multi Hand Trackingが動作しました。
利用したバージョンはv0.7.5です。
(MediaPipeに関連する記事はこちらにまとめてあります。)
留意事項
MediaPipeのバージョン
本記事はMediaPipe v0.7.5を利用していますが、ちょうど本記事を執筆中(2020/7/9)にMediaPipe v0.7.6が公開されました(https://github.com/google/mediapipe/releases/tag/v0.7.6)。インストールガイドにJetson Nanoでの実行方法が追加されたため、公式の方が良いという方はそちらをご覧ください。
https://google.github.io/mediapipe/getting_started/install.html#installing-on-debian-and-ubuntu
なお、公式のインストールガイドでは、bazelをRasPi上でビルドしていますが、本記事では別の方が公開されている、ビルド済みのbazelを利用しています。長いビルド時間を短縮できるという点では、本記事の方が楽かと思います。
インストールにあたって
実行までにかなり時間がかかるので、なにかの作業と並行して進めることをオススメします。
インストール手順
ステップ0:用意するもの
Raspberry Piで動かすのに必要なものです。今回は以下のものを使用しました。ほとんど秋月電子通商で購入できるので参考にリンクを貼っておきます。
- micro SDカード:32GBのものを利用しました。
- SDカードライター
- Jetson Nano開発者キット:B01モデル(カメラ用のMIPI-CSIコネクタが二つあるタイプ)を利用しました。(http://akizukidenshi.com/catalog/g/gM-15359/)
- ACアダプタ(電源):DCプラグ 5V 4A(http://akizukidenshi.com/catalog/g/gM-10660/)。USB TypeB-microでも可能です。5V 2Aなどでも動作はしますが、容量が大きい方が動作が安定するようです(体感、厳密には図っていません)。
- USBキーボード・マウス
- モニタ用ケーブル:HDMI - HDMI(http://akizukidenshi.com/catalog/g/gC-13562/)
- モニタ:HDMI入力
- ネットワーク環境:無線 or 有線。どちらでも問題ありません。
- カメラ:RasPiカメラモジュールV2 or USBカメラ。どちらでも問題ありません。 (カメラがなくても、動画ファイルの処理は可能です。)
また、以下のものがあると良いと思います。
- ヒートシンク・ファン:MediaPipeを動かすとかなり熱くなるので、あると安心して作業できます。(なくても、動かすのが短時間であれば問題ないと思います。)
- アクリルケース:金属部分が他に接触しないので、安心できます。また、ケーブルを挿し込む際など、取り扱いがしやすいので、あると嬉しいです。ヒートシンク・ファンのセットで売ってるものが多いです。
ステップ1:Jetson Nanoをセットアップする
ステップ1-1 :Jetson Nano用のSDカードイメージをダウンロードする
以下のリンクから、Jetson Nano用のSDカードイメージをダウンロードします。
下図の赤枠のリンクからダウンロードできます。6GBとファイルサイズが結構大きいのでご注意ください。
ダウンロードしたら解凍します。
ステップ1-2:SDカードにイメージを書き込む
赤枠下の「Follow these instructions」にしたがって進めます。
ステップ1-3:Ubuntuをセットアップする
SDカードをJetson Nanoに挿し、ディスプレイ・キーボード・マウスを接続します。立ち上がったら、指示にしたがって、Ubuntuをセットアップしてください。
セットアップが終わったら、ターミナルを開き、以下のコマンドで更新しておきます。
sudo apt update sudo apt upgrade -y sudo reboot
ステップ2:MediaPipe をインストールする
公式ガイドにしたがってインストールしていきます。
ステップ2-1:MediaPipeのリポジトリをクローンする
ターミナルを開いて、以下のコマンドを実行します。
cd ~ git clone https://github.com/google/mediapipe.git
ステップ2-2:OpenCVとFFmpegをインストールする
今回は、インストールガイドのOption 2を利用しました。(下のコマンドはcloneしたMediaPipeのフォルダで実行してください)
cd ~/mediapipe chmod +x setup_opencv.sh ./setup_opencv.sh
数十分かかるので、次のステップを並行して進めます。
ステップ2-3:bazelをインストールする
今回は、本記事の冒頭で述べたように、こちらで公開されている、すでにビルド済みのバイナリファイルを利用させていただきました。バージョンは2.0.0を利用しました(0.29.4だと、Hello Worldをビルドするときにエラーで止まりました)。必要なjdk8をインストールし、cloneしたリポジトリに含まれるbazelインストール用のスクリプトを実行します。
sudo apt-get install -y openjdk-8-jdk cd ~ git clone https://github.com/PINTO0309/Bazel_bin.git cd Bazel_bin/2.0.0/Raspbian_Debian_Buster_armhf/openjdk-8-jdk/ ./install.sh # output to /usr/local/bin/bazel
v0.7.5の公式ガイドに記載されてる通常の手順では、ビルドに数時間以上かかり、かつ、以降の手順で動きませんでした。
Hello Worldで動作確認
公式ガイド通りビルドして動作させます。
CPU版の場合、以下のようなコマンドになります。
# cd ~/mediapipe export GLOG_logtostderr=1 bazel run --define MEDIAPIPE_DISABLE_GPU=1 \ mediapipe/examples/desktop/hello_world:hello_world
GPU版の場合、以下のようなコマンドになります。
# cd ~/mediapipe export GLOG_logtostderr=1 bazel run --copt -DMESA_EGL_NO_X11_HEADERS --copt -DEGL_NO_X11 \ mediapipe/examples/desktop/hello_world:hello_world
bazelのビルド後(数十分かかります)、以下のように「Hello World!」が10回表示がされればOKです。
I20200629 11:55:45.702250 28131 hello_world.cc:56] Hello World! I20200629 11:55:45.702352 28131 hello_world.cc:56] Hello World! I20200629 11:55:45.702378 28131 hello_world.cc:56] Hello World! I20200629 11:55:45.702397 28131 hello_world.cc:56] Hello World! I20200629 11:55:45.702419 28131 hello_world.cc:56] Hello World! I20200629 11:55:45.702440 28131 hello_world.cc:56] Hello World! I20200629 11:55:45.702461 28131 hello_world.cc:56] Hello World! I20200629 11:55:45.702484 28131 hello_world.cc:56] Hello World! I20200629 11:55:45.702507 28131 hello_world.cc:56] Hello World! I20200629 11:55:45.702527 28131 hello_world.cc:56] Hello World!
Multi Hand Trackingを動かす
公式ガイド通りビルドして動作させます。カメラを接続してください。
CPU版の場合、以下のようなコマンドになります。
# cd ~/mediapipe bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 \ mediapipe/examples/desktop/multi_hand_tracking:multi_hand_tracking_gpu export GLOG_logtostderr=1 bazel-bin/mediapipe/examples/desktop/multi_hand_tracking/multi_hand_tracking_gpu \ --calculator_graph_config_file=mediapipe/graphs/hand_tracking/multi_hand_tracking_desktop_live.pbtxt
GPU版の場合、以下のようなコマンドになります。
# cd ~/mediapipe bazel build -c opt --copt -DMESA_EGL_NO_X11_HEADERS --copt -DEGL_NO_X11 \ mediapipe/examples/desktop/multi_hand_tracking:multi_hand_tracking_gpu export GLOG_logtostderr=1 bazel-bin/mediapipe/examples/desktop/multi_hand_tracking/multi_hand_tracking_gpu \ --calculator_graph_config_file=mediapipe/graphs/hand_tracking/multi_hand_tracking_desktop_live.pbtxt
カメラがない場合は、動画ファイルを用意し、以下のようにオプションでファイルパスを渡してください。
bazel-bin/mediapipe/examples/desktop/multi_hand_tracking/multi_hand_tracking_gpu \ --calculator_graph_config_file=mediapipe/graphs/hand_tracking/multi_hand_tracking_desktop_live.pbtxt \ --input_video_path="video.mp4" \ --output_video_path="video_gpu.mp4"
bazelのビルド後(数時間かかります)、検出結果のウィンドウが表示されます。(ファイルパスを指定した場合は、少し時間が立った後ファイルが出力されます。GPUで3~4fps程度の処理速度なので、数秒の動画ファイルでも数分かかります。)
検出している様子は、以下の動画のようでした
CPU版では、処理速度は1[fps]程度でした。
GPU版では、処理速度は3~4[fps]程度で、検出の様子は以下のようでした。
商品を取っているところ模擬して、手を検出できるか確認しました。様子は以下の動画のようでした。商品を素早くとっても、手を検出はギリギリできています。
まとめ
今回は、MediaPipe v0.7.5をJetson Nanoにインストールし、Multi Hand Trackingを動かしました。処理速度はGPUを利用して3~4[fps]程度でした。カフェなどでそのまま利用することもなんとか可能に思われました。ただ、常時検出をかけ続けるという使い方よりも、高フレームレートで録画のみを続けておいて、別の手段(重量センサ)で商品検出したときに、その時点の近辺を検出にかける、という使い方の方が、検出の取りこぼしが減らせそうです。
参考にさせて頂いたページ
補足
処理速度をさらに上げるには、以下の方法が利用できそうです。参考となるリンクを貼っておきます。
Jetson Nano + EdgeTPU USB Acceleratorで動かす
デバイスを変える
- Google Edge TPU - Coral Dev Board